#include "dstruct.h"
#include "header.h"

/*****************************JOIN_FILE****************************************
//first checks if all parts are in order and all parts are complete.
// returns 0 if file joined properly.
// 	   1 if parts not in order.
//	   2 if parts incomplete.
------------->doesnot return an int anymore. 14/Nov/2010.
Function &  description:
This will be called by manager of peer(leecher) once all parts are downloaded.
UPDATE: After writing the function i realized this function shud return the 
pointer to new file.
/******************************************************************************/
FILE *join_file(struct file_part *head)//head is the name of the file.
{
	struct file_part *orignal_file = head;
	struct file_part *temp = head;
	int i=1,flag = 0,No_of_parts=0;//ALL OK
	int filesize=0,bytes_read;
	char newfilename[20];
	char partname[20];
	FILE *new_file_ptr;
	char * buffer;

	//go to each node and check if the pointer to data exists.
	while(!flag && temp){
		if(temp->part_num == i && temp->data_ptr != NULL){
			temp = temp->next;
			i++;
		}
		else{
			flag = 1;
			//return flag;
		}
	}
	if(flag)
		return NULL;// indicating error
		//chck for %dwnloaded
	temp = head;
	flag =0;
	while(temp){
		if((temp->percent_downloaded == 100.00) && temp->next){
			
		}
		else{
			flag = 2;
			return NULL;
		}
		temp = temp->next;
	}
	//Now start to join.
	temp = head;			//saving the head pointer
	while(temp){			//calc number of parts and size of entire file.
		No_of_parts++;
		filesize += temp->file_size;
		temp=temp->next;
	}
	temp=head;//go back to head;
	
	buffer = (char *)malloc(sizeof(char)*PARTSIZE);
	
	sprintf(newfilename,"%s",temp->filename);
	new_file_ptr = fopen(newfilename,"a+");			//create space for new file.
	while(temp){
		if(temp->next == NULL){				//last node
			memset(buffer,0,sizeof(buffer));
			sprintf(partname,"%s.part%d",temp->filename,temp->part_num);
			temp->data_ptr = fopen(partname,"r+");
			bytes_read = fread(buffer,1,(filesize-((No_of_parts-1)*(PARTSIZE))),temp->data_ptr);
			fwrite(buffer,1,bytes_read,new_file_ptr);
			fclose(temp->data_ptr);
		}
		else{						//all other nodes
			memset(buffer,0,sizeof(buffer));
			sprintf(partname,"%s.part%d",temp->filename,temp->part_num);
			temp->data_ptr = fopen(partname,"r+");
			bytes_read = fread(buffer,1,PARTSIZE,temp->data_ptr);
			fwrite(buffer,1,bytes_read,new_file_ptr);
			fclose(temp->data_ptr);
		}
		temp=temp->next;
	}
	rewind(new_file_ptr);
	free(buffer);
	fclose(new_file_ptr);
	return new_file_ptr;
}
static float calc_percent(struct file_part* ptr)
{
	int i;
	ptr->data_ptr = fopen(ptr->filename,"r");
	
	fseek (ptr->data_ptr,0,SEEK_END);
  	i = ftell(ptr->data_ptr);
  	rewind (ptr->data_ptr);

	fclose(ptr->data_ptr);
	return	(i/65536)*100;
}

/*****************************CHECK FILE*****************************************
* Func desc: checks whether part of the file is complete.
* arguments:
*@ struct file_part *head: the head pointer(filename)
*@ int part_num: to indicate which part number to chck.
*@enum chck_status....update status into this and return
*return: The function return enum status.
----------------------------------------------------------------------------------
*Function will be called by manager to chck if particular part is complete or not.
* The manager must call this function once for each part..???can this be made into a recursive function to check the entire file???
**********************************************************************************/
/*enum check_file(struct file_part *head,enum chck_status,int part_no)
{
	struct file_part *temp = head;
	FILE * save_dp = temp->data_ptr;
	while(temp->part_num != part_no){
		temp = temp->next;
	}
	printf("Checking part number %d",temp->part_num);

	temp->percent_downloaded = calc_percent(temp);

	temp->data_ptr = save_dp;
	if(temp->percent_downloaded == 0.00){
		return (chck_status = PENDING);
	}
	else if(temp->percent_downloaded == 100.00){
		return (chck_status = COMPLETE);
	}
	else if(temp->percent_downloaded < 100.00){
		return (chck_status = LEECHING);
	}
}
*/
/*
void print_list(struct file_part *head)
{
	struct file_part * temp = head;
	while(temp){
		printf("filename = %s\npart no. = %d\n",temp->filename,temp->part_num);
		printf("file size = %d bytes\n percent downloaded = %f",temp->file_size,temp->percent_downloaded);
		temp=temp->next;
	}
}
*/
